
#include "MyGame.h"
#include "TestCube.h"

#include <functional>

#include <RCRectangle.h>


#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment (lib,"Gdiplus.lib")

//#ifdef _DEBUG
//#define new DEBUG_NEW
//#endif

MyGame::MyGame(void)
{
	camera = new RCCamera(XMFLOAT3(0,0,0),XMFLOAT3(0,1,0),XMQuaternionIdentity());
	AddComponent(std::shared_ptr<IRCGameComponent>(camera));

	setTitle(L"RC Sand Box");

	/*TestCube* testCube = new TestCube();
	testCube->setCamera(camera);
	testCube->setPosition(XMFLOAT3(0,0,5));
	AddComponent(testCube);*/

	int cubes = 8;
	for(int c = 0; c < cubes;c++)
	{
		TestCube* testCube = new TestCube();	
		
		/*if(c != 0)
			testCube->setVisible(false);
*/
		XMFLOAT3 pos;
		XMFLOAT4 col;
		switch(c)
		{
			case 0:
				pos = XMFLOAT3(-1,0,1);
				col = XMFLOAT4(1,1,1,1);
				break;
			case 1:
				pos = XMFLOAT3(1,0,1);
				col = XMFLOAT4(1,0,1,1);
				break;
			case 2:
				pos = XMFLOAT3(-1,0,3);
				col = XMFLOAT4(1,1,0,1);
				break;
			case 3:
				pos = XMFLOAT3(1,0,3);
				col = XMFLOAT4(0,1,1,1);
				break;
			case 4:
				pos = XMFLOAT3(-1,2,1);
				col = XMFLOAT4(0,0,1,1);
				break;
			case 5:
				pos = XMFLOAT3(1,2,1);
				col = XMFLOAT4(1,0,0,1);
				break;
			case 6:
				pos = XMFLOAT3(-1,2,3);
				col = XMFLOAT4(0,1,0,1);
				break;
			case 7:
				pos = XMFLOAT3(1,2,3);
				col = XMFLOAT4(.5,.5,.5,1);
				break;
		}
		testCube->setCamera(camera);
		testCube->setPosition(pos);
		testCube->Color = col;
		
		//AddComponent(std::shared_ptr<IRCGameComponent>(testCube));
	}

	//setClearColor(XMFLOAT4(.8f,.8f,.8f,1));
	rotation = 0;
	rotation2 = 0;

	bg = 0;
	l1 = 0;
	l2 = 0;

	playerPos = XMFLOAT2(200,200);

	for(int m = 0;m<5;m++)
		mines[m] = XMFLOAT2(200 * (m+1),(m + 1) * 60);

	for(int l=0;l<4;l++)
	{
		activeLaser[l] = false;
		lasers[l] = XMFLOAT2(900,0);
	}

	//vUpdateables.clear();
	//vDrawables.clear();
	//vGameComponents.clear();
}


MyGame::~MyGame(void)
{ 
	camera = nullptr;

	pMineTexture->Release();
	pShipTexture->Release();

	spriteBatch = nullptr;

	mainBG->Release();
	layer1->Release();
	layer2->Release();

	laser->Release();
}

void MyGame::Update(float time, std::vector<IUpdateable*>* updateables)
{
	HandleKeyboardInput();
	
	int cnt = 1;
	for(auto c = vGameComponents.begin();c != vGameComponents.end();c++)
	{
	//	TestCube* obj = dynamic_cast<TestCube*>((*(*c)));

	//	if(obj != nullptr)
	//		obj->Rotate(XMVectorSet(-1,1,1,0),.001f * cnt++ );

		/*TestSpriteBatch* obj2 = dynamic_cast<TestSpriteBatch*>((*(*c)));

		if(obj2 != nullptr)
			obj2->Rotate(XMVectorSet(0,0,1,0),.001f);*/
	}

	RCGame::Update(time,updateables);
}

void MyGame::HandleKeyboardInput()
{
	float spd = .05f;
	float rotSpd = .01f;

	float playerSpeed = 8.0f;

	if (KeyboardManager.getState()[DIK_ESCAPE]/128)
		RCGame::Stop();

	if (KeyboardManager.getState()[DIK_LEFT]/128)
	{
		camera->Rotate(XMVectorSet(0,1,0,0),-rotSpd);
		playerPos.x -= playerSpeed;
	}

	if (KeyboardManager.getState()[DIK_RIGHT]/128)
	{
		camera->Rotate(XMVectorSet(0,1,0,0),rotSpd);
		playerPos.x += playerSpeed;
	}

	if(KeyboardManager.getState()[DIK_UP]/128)
	{
		camera->Rotate(XMVectorSet(1,0,0,0),-rotSpd);
		playerPos.y -= playerSpeed;
	}

	if(KeyboardManager.getState()[DIK_DOWN]/128)
	{
		camera->Rotate(XMVectorSet(1,0,0,0),rotSpd);
		playerPos.y += playerSpeed;
	}

	if(playerPos.x < 0)
		playerPos.x = 0;
	if(playerPos.x > GraphicsDevice.getViewPort().Width)
		playerPos.x = GraphicsDevice.getViewPort().Width;

	if(playerPos.y < 0)
		playerPos.y = 0;
	if(playerPos.y > GraphicsDevice.getViewPort().Height)
		playerPos.y = GraphicsDevice.getViewPort().Height;

	if(KeyboardManager.getState()[DIK_SPACE]/128)
	{
		camera->setOrientation(XMQuaternionIdentity());

	}

	if(KeyboardManager.getState()[DIK_W]/128)
		camera->Translate(XMFLOAT3(0,0,spd));

	if(KeyboardManager.getState()[DIK_S]/128)
		camera->Translate(XMFLOAT3(0,0,-spd));

	if(KeyboardManager.getState()[DIK_A]/128)
		camera->Translate(XMFLOAT3(-spd,0,0));

	if(KeyboardManager.getState()[DIK_D]/128)
		camera->Translate(XMFLOAT3(spd,0,0));

}

void MyGame::Initialize()
{
	RCGame::Initialize();

	//laserSound = RCSound(this,"sound01.wav");
	//laserSound = RCSoundWav();
	laserSound.LoadAsset(L"sound01.wav");
	bangSound.LoadAsset(L"explosion.wav");
	//laserSound = RCSound(this,"laserFire.wav");
	D3DX11CreateShaderResourceViewFromFile(getGraphicsDevice()->getDevice(), L"mineAnimation.png", NULL, NULL, &pMineTexture, NULL);
	D3DX11CreateShaderResourceViewFromFile(getGraphicsDevice()->getDevice(), L"shipAnimation.png", NULL, NULL, &pShipTexture, NULL);

	D3DX11CreateShaderResourceViewFromFile( getGraphicsDevice()->getDevice(), L"mainbackground.png", NULL, NULL, &mainBG, NULL );
	D3DX11CreateShaderResourceViewFromFile( getGraphicsDevice()->getDevice(), L"bgLayer1.png", NULL, NULL, &layer1, NULL );
	D3DX11CreateShaderResourceViewFromFile( getGraphicsDevice()->getDevice(), L"bgLayer2.png", NULL, NULL, &layer2, NULL );
	D3DX11CreateShaderResourceViewFromFile( getGraphicsDevice()->getDevice(), L"laser.png", NULL, NULL, &laser, NULL );

	D3DX11CreateShaderResourceViewFromFile( getGraphicsDevice()->getDevice(), L"whitePixel.jpg", NULL, NULL, &whitePixel, NULL );

	D3DX11CreateShaderResourceViewFromFile( getGraphicsDevice()->getDevice(), L"explosion.png", NULL, NULL, &bangTexture, NULL );
	

	// Compile the pixel shader
	ID3DBlob* pPSBlob = NULL;
	HRESULT hr = RCGame::CompileShaderFromFile( L"SpriteBatch2.fx", "PS", "ps_4_0", &pPSBlob );
	if( FAILED( hr ) )
	{
		MessageBox( NULL,
					L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
		return;
	}

	// Create the pixel shader
	hr = GraphicsDevice.getDevice()->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &pPixelShader );

	spriteBatch = new RCSpriteBatch(getGraphicsDevice());

	D3D11_TEXTURE2D_DESC textureDesc;
	HRESULT result;
	D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
	D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;


	// Initialize the render target texture description.
	ZeroMemory(&textureDesc, sizeof(textureDesc));

	// Setup the render target texture description.
	textureDesc.Width = GraphicsDevice.getViewPort().Width;
	textureDesc.Height = GraphicsDevice.getViewPort().Height;
	textureDesc.MipLevels = 1;
	textureDesc.ArraySize = 1;
	textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	textureDesc.SampleDesc.Count = 1;
	textureDesc.Usage = D3D11_USAGE_DEFAULT;
	textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
	textureDesc.CPUAccessFlags = 0;
	textureDesc.MiscFlags = 0;

	// Create the render target texture.
	result = GraphicsDevice.getDevice()->CreateTexture2D(&textureDesc, NULL, &m_renderTargetTexture);
	
	// Setup the description of the render target view.
	renderTargetViewDesc.Format = textureDesc.Format;
	renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
	renderTargetViewDesc.Texture2D.MipSlice = 0;

	// Create the render target view.
	result = GraphicsDevice.getDevice()->CreateRenderTargetView(m_renderTargetTexture, &renderTargetViewDesc, &m_renderTargetView);
	
	// Setup the description of the shader resource view.
	shaderResourceViewDesc.Format = textureDesc.Format;
	shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
	shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
	shaderResourceViewDesc.Texture2D.MipLevels = 1;

	// Create the shader resource view.
	result = GraphicsDevice.getDevice()->CreateShaderResourceView(m_renderTargetTexture, &shaderResourceViewDesc, &m_shaderResourceView);
	
	
}

void MyGame::Draw(float time, std::vector<IDrawable*>* drawables)
{
	clearColor = XMFLOAT4(1,0,0,1);
	GraphicsDevice.Clear(clearColor, D3D11_CLEAR_DEPTH,1.0f,0);

	/*IDXGISurface1* surface;
	m_shaderResourceView->QueryInterface(__uuidof(IDXGISurface1), (void **)(&surface));*/
	GraphicsDevice.getDeviceContext()->OMSetRenderTargets(1, &m_renderTargetView, GraphicsDevice.getDepthStencilView());	
		
	/*float cc[4] = {0,0,1,1};
	GraphicsDevice.getDeviceContext()->ClearRenderTargetView(m_renderTargetView,cc);*/

	RCGame::Draw(time,drawables);

	ID3D11BlendState* bs;
	spriteBatch->getNonPremultiplied(&bs);

	XMVECTOR imgSize = GetTextureSize(mainBG);

	spriteBatch->Begin(Immediate);

	spriteBatch->Draw(mainBG,XMFLOAT4(0-bg,0,GraphicsDevice.getViewPort().Width,GraphicsDevice.getViewPort().Height),XMFLOAT2(0,0),0,XMFLOAT4(1,1,1,1),0);
	spriteBatch->Draw(mainBG,XMFLOAT4(GraphicsDevice.getViewPort().Width-bg,0,GraphicsDevice.getViewPort().Width,GraphicsDevice.getViewPort().Height),XMFLOAT2(0,0),0,XMFLOAT4(1,1,1,1),0);
	
	spriteBatch->End();

	
	//spriteBatch->Begin(Deferred,bs,nullptr,nullptr,nullptr,[&](){SetPS();});
	spriteBatch->Begin(Deferred,bs,nullptr,nullptr,nullptr,nullptr);
	
	spriteBatch->Draw(layer1,XMFLOAT4(0-l1,0,GraphicsDevice.getViewPort().Width,GraphicsDevice.getViewPort().Height),XMFLOAT2(0,0),0,XMFLOAT4(1,1,1,1),0);
	spriteBatch->Draw(layer1,XMFLOAT4(GraphicsDevice.getViewPort().Width-l1,0,GraphicsDevice.getViewPort().Width,GraphicsDevice.getViewPort().Height),XMFLOAT2(0,0),0,XMFLOAT4(1,1,1,1),0);
	//spriteBatch->End();

	//spriteBatch->Begin(Deferred,bs,nullptr,nullptr,nullptr,nullptr);
	spriteBatch->Draw(layer2,XMFLOAT4(0-l2,0,GraphicsDevice.getViewPort().Width,GraphicsDevice.getViewPort().Height),XMFLOAT2(0,0),0,XMFLOAT4(1,1,1,1),0);
	spriteBatch->Draw(layer2,XMFLOAT4(GraphicsDevice.getViewPort().Width-l2,0,GraphicsDevice.getViewPort().Width,GraphicsDevice.getViewPort().Height),XMFLOAT2(0,0),0,XMFLOAT4(1,1,1,1),0);
	//spriteBatch->End();

	//spriteBatch->Begin(Deferred,bs,nullptr,nullptr,nullptr,nullptr);
	spriteBatch->Draw(pShipTexture, XMFLOAT4(115 * (int)rotation2, 0, 115, 69), XMFLOAT4(playerPos.x, playerPos.y, 115, 69), XMFLOAT2(57.5f, 34.5f), rotation, XMFLOAT4(1, 1, 1, 1), 0);
	//spriteBatch->End();

	RCRectangle shipRect(XMFLOAT4(playerPos.x-57.5f,playerPos.y-34.5f,115,69));
	
	//spriteBatch->Begin(Instanced,bs,nullptr,nullptr,nullptr,nullptr);
	for(int m = 0;m<5;m++)
	{
		spriteBatch->Draw(pMineTexture, XMFLOAT4(47 * (int)rotation2, 0, 47, 61), XMFLOAT4(mines[m].x, mines[m].y, 47, 61), XMFLOAT2(23.5, 30.5), 0, XMFLOAT4(1, 1, 1, 1), 0);
		RCRectangle mineRect(XMFLOAT4(mines[m].x-23.5,mines[m].y-30.5,47,61));

		if(shipRect.Intersects(mineRect))
		{
			spriteBatch->Draw(whitePixel, XMFLOAT4(0,0,115,69), XMFLOAT4(playerPos.x-57.5f,playerPos.y-34.5f,115,69),XMFLOAT2(0,0),rotation,XMFLOAT4(1,0,0,.25),0);
			spriteBatch->Draw(whitePixel, XMFLOAT4(0,0,47,61), XMFLOAT4(mines[m].x-23.5,mines[m].y-30.5,47,61),XMFLOAT2(0,0),0,XMFLOAT4(1,0,0,.25),0);

			RCRectangle both = RCRectangle::Union(shipRect,mineRect);
			spriteBatch->Draw(whitePixel, XMFLOAT4(0,0,47,61), XMFLOAT4(both.X,both.Y,both.Width,both.Height),XMFLOAT2(0,0),0,XMFLOAT4(0,0,1,.25),0);

			
			RCRectangle intrsect = RCRectangle::Intersect(shipRect,mineRect);
			spriteBatch->Draw(whitePixel, XMFLOAT4(0,0,47,61), XMFLOAT4(intrsect.X,intrsect.Y,intrsect.Width,intrsect.Height),XMFLOAT2(0,0),0,XMFLOAT4(1,1,1,.5),0);
		}

		if(shipRect.Contains(mineRect))
			spriteBatch->Draw(whitePixel, XMFLOAT4(0,0,47,61), XMFLOAT4(mines[m].x-23.5,mines[m].y-30.5,47,61),XMFLOAT2(0,0),0,XMFLOAT4(0,1,0,.25),0);
		
		mines[m].x -= 3;

		
//		mineRect->~RCRectangle();

		if(mines[m].x < -50)
			mines[m].x = 850;
	}
	

	//spriteBatch->End();

	int lcnt = 0;
	for(int l = 0;l<4;l++)
	{
		if(!activeLaser[l])
			lcnt++;
	}
	if(lcnt == 4)
	{
		activeLaser[0] = true;
		//laserSound.PlayWav();
		//laserSound.Play(L"sound01.wav");
		lasers[0].x = playerPos.x + 57.5;
		lasers[0].y = playerPos.y;
	}

	//spriteBatch->Begin(Instanced,bs,nullptr,nullptr,nullptr,nullptr);
	for(int l = 0;l<4;l++)
	{
		if(activeLaser[l])
		{
			spriteBatch->Draw(laser, XMFLOAT4(lasers[l].x,lasers[l].y,46,16),XMFLOAT2(23,8),0,XMFLOAT4(1,1,1,1),0);
			lasers[l].x += 20;

			if(lasers[l].x > GraphicsDevice.getViewPort().Width + 23)
				activeLaser[l] = false;
			else
			{
				shipRect = RCRectangle(XMFLOAT4(lasers[l].x,lasers[l].y,46,16));
				for(int m = 0;m<5;m++)
				{
					RCRectangle mineRect(XMFLOAT4(mines[m].x-23.5,mines[m].y-30.5,47,61));

					if(shipRect.Intersects(mineRect))
					{
						BangAnim* bang = new BangAnim(mines[m]);
						explosion.push_back(std::shared_ptr<BangAnim>(bang));
						mines[m].x = 850;
						activeLaser[l] = false;

						//laserSound.PlayMusic(L"explosion.wav");
						bangSound.Play(L"explosion.wav");

						// Do explosion and remove bullet and mine from the active pool.
						
						/*spriteBatch->Draw(whitePixel, XMFLOAT4(0,0,115,69), XMFLOAT4(lasers[l].x,lasers[l].y,46,16),XMFLOAT2(0,0),rotation,XMFLOAT4(1,0,0,.25),0);
						spriteBatch->Draw(whitePixel, XMFLOAT4(0,0,47,61), XMFLOAT4(mines[m].x-23.5,mines[m].y-30.5,47,61),XMFLOAT2(0,0),0,XMFLOAT4(1,0,0,.25),0);

						RCRectangle both = RCRectangle::Union(shipRect,mineRect);
						spriteBatch->Draw(whitePixel, XMFLOAT4(0,0,47,61), XMFLOAT4(both.X,both.Y,both.Width,both.Height),XMFLOAT2(0,0),0,XMFLOAT4(0,0,1,.25),0);

			
						RCRectangle intrsect = RCRectangle::Intersect(shipRect,mineRect);
						spriteBatch->Draw(whitePixel, XMFLOAT4(0,0,47,61), XMFLOAT4(intrsect.X,intrsect.Y,intrsect.Width,intrsect.Height),XMFLOAT2(0,0),0,XMFLOAT4(1,1,1,.5),0);*/
					}

					if(shipRect.Contains(mineRect))
						spriteBatch->Draw(whitePixel, XMFLOAT4(0,0,47,61), XMFLOAT4(mines[m].x-23.5,mines[m].y-30.5,47,61),XMFLOAT2(0,0),0,XMFLOAT4(0,1,0,.25),0);
				}
			}
		}
		else
		{
			lasers[l].x = playerPos.x + 57.5;
			lasers[l].y = playerPos.y;
			
			int nextl = l - 1;
			if(l == 0)
				nextl = 3;

			float dist = sqrt((lasers[nextl].x-lasers[l].x) + (lasers[nextl].y-lasers[l].y));
						
			if(dist > sqrt(155))
			{
				//laserSound.PlayWav();
				laserSound.Play(L"sound01.wav");
				activeLaser[l] = true;
			}
		}		
	}
	// Exposions
	if(explosion.size() > 0)
	{
		std::list<std::shared_ptr<BangAnim>> droplist;
		for(auto e = explosion.rbegin();e != explosion.rend();e++)
		{
			if((*e)->frame < 12)
			{
				spriteBatch->Draw(bangTexture, XMFLOAT4(133.5 * (int)(*e)->frame,0,133.5,134), XMFLOAT4((*e)->position.x,(*e)->position.y,64,64),XMFLOAT2(30.5,30.5),0,XMFLOAT4(1,1,1,1),0);
				(*e)->frame += .5f;			
			}			
			else
				droplist.push_back((*e));
		}		
		if(droplist.size() > 0)
		{
			for(auto e = droplist.begin();e != droplist.end();e++)
				explosion.remove((*e));

			droplist.clear();
		}
	}
	spriteBatch->End();
	//spriteBatch->Draw(pTextureRV, XMFLOAT4(200,200,32,32),XMFLOAT2(128,128),rotation2,XMFLOAT4(0,0,1,1),0);
	//spriteBatch->Draw(pTextureRV, XMFLOAT4(216,216,32,32),XMFLOAT2(32,32),-rotation,XMFLOAT4(0,1,1,1),0);
	//spriteBatch->Draw(pTextureRV, XMFLOAT2(200,200), XMFLOAT2(32,32),XMFLOAT2(-512,-512),rotation,XMFLOAT4(0,1,0,1));

	//rotation -= .01f;
	rotation2 += .5f;

	bg += .5f;
	l1+=1;
	l2+=2;

	if(bg > GraphicsDevice.getViewPort().Width)
		bg = 0;

	if(l1 > GraphicsDevice.getViewPort().Width)
		l1 = 0;

	if(l2 > GraphicsDevice.getViewPort().Width)
		l2 = 0;

	if(rotation2 > 8)
		rotation2 = 0;


	//	RCGame::Draw(time,drawables);
	//http://www.rastertek.com/dx11tut22.html

	ID3D11RenderTargetView* rtv = GraphicsDevice.getRenderTerget();
	GraphicsDevice.getDeviceContext()->OMSetRenderTargets(1, &rtv, GraphicsDevice.getDepthStencilView());

	/*float ccl[4] = {0,0,0,1};
	GraphicsDevice.Clear(ccl,0,0,0);*/
	//GraphicsDevice.getDeviceContext()->ClearRenderTargetView(m_renderTargetView,ccl);

	ID3D11BlendState* opaque;
	spriteBatch->getOpaque(&opaque);
	spriteBatch->Begin(Deferred,opaque,nullptr,nullptr,nullptr,[&](){SetPS();});

	float width = GraphicsDevice.getViewPort().Width / 2;
	float height = GraphicsDevice.getViewPort().Height / 2;

	/*spriteBatch->Draw(m_shaderResourceView,XMFLOAT4(width,0,width,height),XMFLOAT2(0,0),0,XMFLOAT4(1,1,1,1),0);
	spriteBatch->Draw(m_shaderResourceView,XMFLOAT4(0,0,width,height),XMFLOAT2(0,0),0,XMFLOAT4(1,1,1,1),0);
	spriteBatch->Draw(m_shaderResourceView,XMFLOAT4(0,height,width,height),XMFLOAT2(0,0),0,XMFLOAT4(1,1,1,1),0);
	spriteBatch->Draw(m_shaderResourceView,XMFLOAT4(width,height,width,height),XMFLOAT2(0,0),0,XMFLOAT4(1,1,1,1),0);
*/
	spriteBatch->Draw(m_shaderResourceView,XMFLOAT4(0,0,800,480),XMFLOAT2(0,0),0,XMFLOAT4(1,1,1,1),0);

	//HDC hdc; 
	//surface->GetDC(TRUE,&hdc);
	//
	////Graphics* graphics = Graphics::FromImage(&bmp);
	//Graphics graphics(hdc);
	//graphics.SetSmoothingMode(Gdiplus::SmoothingMode::SmoothingModeHighQuality);
	//graphics.Clear(Gdiplus::Color(255,255,255,255));
	//graphics.SetTextRenderingHint(Gdiplus::TextRenderingHint::TextRenderingHintAntiAlias);

	//FontFamily ff (L"EAN-8");	
	//Font font(&ff,60,FontStyleRegular, UnitPixel);

	//SolidBrush brush (Color(0,0,0,255));
	//PointF pointF (10.0f,20.0f);
	////graphics->DrawString(L"12345677",-1,&font,origin,&b);
	//WCHAR* str = L"Hello World!";
	//graphics.DrawString(str, -1, &font, pointF, &brush);

	spriteBatch->End();
	
	
	//Graphics graphics(GetDC(GraphicsDevice.getWindowHandle()));
	//Pen      pen(Color(255, 0, 0, 255));
	//graphics.DrawLine(&pen, 0, 0, 200, 100);
	
}

void MyGame::SetPS()
{
	GraphicsDevice.getDeviceContext()->PSSetShader( pPixelShader, NULL, 0 );
}